package com.cal.utms.dao.user_maintenance;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;

import com.cal.utms.entity.MenuScreen;
import com.cal.utms.entity.Screen;
import com.cal.utms.entity.User;
import com.cal.utms.entity.UserGroup;
import com.cal.utms.entity.UserGroupScreen;
import com.cal.utms.logAudit.AuditLogInterceptor;
import com.cal.utms.util.HibernateUtil;

public class UserDaoImpl implements UserDao {

	@Override
	public Object saveUser(User user) {
		Object obj = null;
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			obj = session.save(user);
			tx.commit();
		} catch (Exception ex) {
			tx.rollback();
			ex.printStackTrace();
		} finally {
			session.close();
		}
		return obj;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UserGroup> getAllUserGruop() {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<UserGroup> groups = new ArrayList<UserGroup>();
		try {
			tx = session.beginTransaction();
			groups = session.createQuery("from UserGroup").list();
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
		} finally {
			session.close();
		}
		return groups;
	}

	@Override
	public UserGroup getUserGroupById(int userGroupId) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction transaction = null;
		UserGroup userGroup = null;
		try {
			transaction = session.beginTransaction();
			userGroup = (UserGroup) session.createQuery("From UserGroup G where G.id=:id").setParameter("id", userGroupId).uniqueResult();
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null)
				transaction.rollback();
		} finally {
			session.close();
		}
		return userGroup;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<User> getAllUsers() {
		Session session = HibernateUtil.getSession().openSession();
		Transaction transaction = null;
		List<User> users = new ArrayList<User>();
		try {
			transaction = session.beginTransaction();
			users = session.createQuery("From User C").list();
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null)
				transaction.rollback();
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return users;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<MenuScreen> getAllMenus() {
		Session session = HibernateUtil.getSession().openSession();
		Transaction transaction = null;
		List<MenuScreen> menuScreens = new ArrayList<MenuScreen>();
		try {
			transaction = session.beginTransaction();
			menuScreens = session.createQuery("From MenuScreen M").list();
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null)
				transaction.rollback();
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return menuScreens;
	}

	@SuppressWarnings("unchecked")
	public List<User> getFMUserList() {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<User> fmList = null;
		try {
			tx = session.beginTransaction();
			fmList = session.createQuery("select u from User u join u.userGroup ug where ug.fundManager=1").list();
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
		} finally {
			session.close();
		}
		return fmList;
	}

	public User getById(Integer id) {
		Session session = HibernateUtil.getSession().openSession();
		User user = null;
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			user = (User) session.get(User.class, id);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return user;
	}

	@Override
	public Object saveUserGroup(UserGroup userGroup, List<UserGroupScreen> groupScreens) {
		Object obj = null;
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			obj = session.save(userGroup);

			// session.createQuery("delete from UserGroupScreen UG where UG.userGroup.id=:grpid").setParameter("grpid",group).executeUpdate();

			for (UserGroupScreen userGroupScreen : groupScreens) {
				userGroupScreen.getId().setUserGroupId((Integer) obj);
				session.merge(userGroupScreen);
			}
			tx.commit();
		} catch (Exception ex) {
			tx.rollback();
			ex.printStackTrace();
		} finally {
			session.close();
		}
		return obj;
	}

	@Override
	public Object updateUser(User user) {
		Object obj = null;
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			obj = session.merge(user);
			tx.commit();
		} catch (Exception ex) {
			tx.rollback();
			ex.printStackTrace();
		} finally {
			session.close();
		}
		return obj;
	}

	@Override
	public User getUserByUsername(String userName) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		User user = null;
		try {
			tx = session.beginTransaction();
			user = (User) session.createQuery("from User U where (UPPER(U.userName)=:loginName)").setParameter("loginName", userName).uniqueResult();
			tx.commit();
		} catch (Exception ex) {
			tx.rollback();
			ex.printStackTrace();
		} finally {
			session.close();
		}
		return user;
	}

	@Override
	public short changePassword(User user, String password) {
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.createQuery("UPDATE User U set U.password=:password WHERE U.id=:id").setParameter("password", password).setParameter("id", user.getId()).executeUpdate();
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return 0;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<MenuScreen> getMenuByGroupId(int groupid) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<MenuScreen> menus = null;
		try {
			tx = session.beginTransaction();
			menus = session.createQuery("select U.menuScreen from UserToMenu U where U.userGroup.id=:groupid").setParameter("groupid", groupid).list();
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return menus;
	}

	@Override
	public UserGroup getUserGroupByCode(String groupCode) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		UserGroup group = null;
		try {
			tx = session.beginTransaction();
			group = (UserGroup) session.createQuery("From UserGroup G where G.groupCode=:code").setParameter("code", groupCode).uniqueResult();
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return group;
	}

	@Override
	public Screen getScreenById(int screenid) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		Screen screen = null;
		try {
			tx = session.beginTransaction();
			screen = (Screen) session.get(Screen.class, screenid);
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return screen;
	}

	public Object updateUserGroup(UserGroup userGroup, List<UserGroupScreen> groupScreens) {
		Object obj = null;
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession();
		interceptor.setSession(session);
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			obj = session.merge(userGroup);
			long count = (Long) session.createQuery("select count(*) from UserGroupScreen UG where UG.id.userGroupId=:grpid").setParameter("grpid", userGroup.getId())
					.uniqueResult();
			if (count > 0) {
				session.createQuery("delete from UserGroupScreen UG where UG.id.userGroupId=:grpid").setParameter("grpid", userGroup.getId()).executeUpdate();
				if (groupScreens.size() > 0) {
					for (UserGroupScreen userGroupScreen : groupScreens) {
						session.save(userGroupScreen);
					}
				}
			} else {
				for (UserGroupScreen userGroupScreen : groupScreens) {
					session.save(userGroupScreen);
				}
			}
			tx.commit();
		} catch (Exception ex) {
			tx.rollback();
			ex.printStackTrace();
		} finally {
			session.close();
		}
		return obj;
	}

	public List<User> getFundManagerList() {
		Session session = HibernateUtil.getSession().openSession();
		// Criteria cr =
		// session.createCriteria(Deal.class).createAlias("dealType", "type");
		Criteria cr = session.createCriteria(User.class);
		ProjectionList projectionList = Projections.projectionList();
		projectionList.add(Projections.property("id"), "id");
		projectionList.add(Projections.property("fullName"), "fullName");
		projectionList.add(Projections.property("designation"), "designation");
		cr.setProjection(projectionList);
		cr.createAlias("userGroup", "userGrp");
		cr.add(Restrictions.eq("userGrp.fundManager", (byte) 1));
		cr.setResultTransformer(Transformers.aliasToBean(User.class));
		@SuppressWarnings("unchecked")
		List<User> list = cr.list();
		session.close();
		return list;
	}

	public UserGroupScreen getUserGroupScreenByGroup(int screenid, int id) {
		UserGroupScreen screen = null;
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			screen = (UserGroupScreen) session.createQuery("from UserGroupScreen UG where UG.id.userGroupId=:grpid and UG.id.screenId=:screenid").setParameter("grpid", id)
					.setParameter("screenid", screenid).uniqueResult();
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return screen;
	}

	@SuppressWarnings("unchecked")
	public List<UserGroupScreen> getScreenBygroup(int groupid) {
		List<UserGroupScreen> screens = null;
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			screens = session.createQuery("from UserGroupScreen UG where UG.id.userGroupId=:grpid").setParameter("grpid", groupid).list();
			tx.commit();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return screens;
	}

	public int getMenuIdByScreenId(int id) {
		int menuId = 0;
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			menuId = (Integer) session.createQuery("select M.id from MenuItem M where M.screen.id=:screenid").setParameter("screenid", id).uniqueResult();
			tx.commit();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return menuId;
	}
}
